using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace Super
{
	public class ExcelNoteSO : ScriptableObject
	{

		public List<ExcelNoteNode> Notes = new List<ExcelNoteNode>();

		private static ExcelNoteSO ins;
		public static ExcelNoteSO Ins
		{
			get
			{
				if (ins == null)
				{
					string path = DefaultConfig.excelNotePath;
					ins = AssetUtil.ALoadAsset<ExcelNoteSO>(path);
#if UNITY_EDITOR
					if (ins == null)
					{
						ins = ScriptableObject.CreateInstance<ExcelNoteSO>();
						AssetDatabase.CreateAsset(ins, path);
						AssetDatabase.SaveAssets();
						AssetDatabase.Refresh();
					}
#endif
				}
				return ins;
			}
		}

		private void AddNode(ExcelNoteNode node)
		{
			ExcelNoteNode oldNode = null;
			int oldNodeIndex = -1;
			for (int i = 0; i < Notes.Count; i++)
			{
				if (node.excelPath == Notes[i].excelPath)
				{
					oldNode = Notes[i];
					oldNodeIndex = i;
					break;
				}
			}
			if (oldNode != null)
			{
				ClearNodeCache(oldNode);
				Notes.RemoveAt(oldNodeIndex);
			}

			Notes.Add(node);
#if UNITY_EDITOR
			EditorUtility.SetDirty(this);
#endif
		}

		public ExcelNoteNode SetTableInfo(string excelPath)
		{
			ExcelNoteNode node = new ExcelNoteNode(excelPath);
			List<string> sheetNames = ExcelUtil.GetExcelTableNames(excelPath);
			for (int i = 0; i < sheetNames.Count; i++)
			{
				ExcelTableInfo info = ExcelUtil.GetTableInfo(excelPath, i);
				string SOPath = string.Format(DefaultConfig.excelTableSOPath, info.tableName);
				node.NodeNames.Add(info.nodeName);
				node.TableNames.Add(info.tableName);
				node.TablePaths.Add(info.tablePath);
				node.SOPaths.Add(SOPath);
			}
			AddNode(node);
			return node;
		}

		public ExcelNoteNode FindTableInfo(string excelPath)
		{
			for (int i = 0; i < Notes.Count; i++)
			{
				if (Notes[i].excelPath == excelPath)
				{
					return Notes[i];
				}
			}
			return null;
		}

		public Type GetTableNodeType(ExcelNoteNode node, int index)
		{
			Type type = null;
			if (node != null)
			{
				type = Type.GetType("Super." + node.NodeNames[index]);
			}
			return type;
		}
		public Type GetTableClassType(ExcelNoteNode node, int index)
		{
			Type type = null;
			if (node != null)
			{
				type = Type.GetType("Super." + node.TableNames[index]);
			}
			return type;
		}

		public void Remove(string excelPath)
		{
			for (int i = 0; i < Notes.Count; i++)
			{
				if (Notes[i].excelPath == excelPath)
				{
					ClearNodeCache(Notes[i]);
					Notes.RemoveAt(i);
					break;
				}
			}
#if UNITY_EDITOR
			EditorUtility.SetDirty(this);
#endif
		}
		public void ClearNodeCache(ExcelNoteNode node)
		{
#if UNITY_EDITOR
			foreach (string path in node.SOPaths)
				AssetDatabase.DeleteAsset(path);

			foreach (string path in node.TablePaths)
				AssetDatabase.DeleteAsset(path);
#endif
		}

		public bool CheckIfSetTableInfo(string excelPath)
		{
			ExcelNoteNode node = FindTableInfo(excelPath);
			if (node == null || node.NodeNames.Count == 0 || node.TableNames.Count == 0)
			{
				return false;
			}
			return true;
		}

		public bool CheckIfSetTabelSO(string excelPath)
		{
			ExcelNoteNode node = FindTableInfo(excelPath);
			if (node == null || node.SOPaths.Count == 0)
			{
				return false;
			}

			for (int i = 0; i < node.SOPaths.Count; i++)
			{
				if (!AssetUtil.AExist(node.SOPaths[i]))
				{
					return false;
				}
			}
			return true;
		}
	}

}
